#include "../include/rpc_server.h"
#include "../include/json_serializer.h"

#include <muduo/base/Logging.h>
#include <muduo/base/CountDownLatch.h>

// 私有方法
// 处理客户端的连接事件
void scRpc::RpcServer::OnConnection(const muduo::net::TcpConnectionPtr& conn) {
	LOG_INFO << conn->peerAddress().toIpPort() << " -> " << conn->localAddress().toIpPort() << " is " << (conn->connected() ? "UP" : "DOWN");
}
// 处理客户端 发送的信息
// 处理接受到的RPC请求
void scRpc::RpcServer::OnMessage(const muduo::net::TcpConnectionPtr& conn, muduo::net::Buffer* buf, muduo::Timestamp time) {
	std::string msg(buf->retrieveAllAsString());	// 缓冲区读数据
	LOG_DEBUG << "Received: " << msg;	// 输出收到的消息

	RpcRequest request;
	// 反序列化 JSON to RpcRequest
	if (!JsonSerializer::Deserialize(msg, request)) {
		// 反序列化失败 就给错误日志
		LOG_ERROR << "Invalid RPC request format";
		RpcResponse response;
		// 解析错误需要设置
		response.error = {{"code", -32700}, {"message", "Parse error"}};
		response.id = request.id;
		SendResponse(conn, response);
		return;
	}
	// 请求方法 对应的处理函数 find一下
	// auto 不好识别  就使用std::function
	std::function<nlohmann::json(const nlohmann::json&)> handler;
	// 生命周期注意  保证线程安全
	{
		std::lock_guard<std::mutex> lock(handlersMutex_);
		// 迭代器方式查找
		auto it = handlers_.find(request.method);	// 方法名对应的处理函数
		if (it == handlers_.end()) {
			// 没找到 就给错误 
			RpcResponse response;
			response.error = {{"code", -32601}, {"message", "Method not found"}};
			response.id = request.id;
			SendResponse(conn, response);
			return;
		}
		handler = it->second;	// 获取对应的处理函数
	}

	// 处理函数 处理之后就给结果 异常就throw  内部错误
	try {
		RpcResponse response;
		response.ans = handler(request.params);	
		// set 请求ID
		response.id = request.id;
		SendResponse(conn, response);	// 给响应
	} catch (const std::exception& e) {
		RpcResponse response;
        response.error = {{"code", -32603}, {"message", e.what()}};
        response.id = request.id;
        SendResponse(conn, response);  // 发送错误响应
	}
}
// 服务端给客户端 返还响应
void scRpc::RpcServer::SendResponse(const muduo::net::TcpConnectionPtr& conn, const RpcResponse& response) {
	std::string msg = JsonSerializer::Serialize(response);
	// 响应对象 --> JSON 字符串
	conn->send(msg);
}

// 构造函数，初始化RpcServer实例
// loop：事件循环，负责处理异步事件
// listenAddr：服务器监听的地址和端口
scRpc::RpcServer::RpcServer(muduo::net::EventLoop* loop, const muduo::net::InetAddress& listenAddr, int threadNum) : server_(loop, listenAddr, "RpcServer") {
	// 初始化TcpServer对象，绑定事件循环和监听地址 
    // 设置连接回调，当连接建立或断开时调用OnConnection
	server_.setConnectionCallback(std::bind(&RpcServer::OnConnection, this, std::placeholders::_1));

	// 消息回调
	server_.setMessageCallback(std::bind(&RpcServer::OnMessage, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));

	// 初始化就是预先设置
	// 设置工作线程数量
	if (threadNum > 0)	server_.setThreadNum(threadNum);
}

// 注册RPC 对应的处理函数
// method  --> 方法名
// handler --> 处理函数
void scRpc::RpcServer::RegisterHandler(const std::string& method, std::function<nlohmann::json(const nlohmann::json&)> handler) {
	// 加锁 
	std::lock_guard<std::mutex> lock(handlersMutex_);
	// handlers 中注册方法和处理函数
	handlers_[method] = handler;
}
// 开启服务器 开始监听 处理客户端的request
void scRpc::RpcServer::start() {
	muduo::CountDownLatch latch(1);  // 创建一个计数器，确保连接建立后才继续
	// 连接回调
	server_.setConnectionCallback([&](const muduo::net::TcpConnectionPtr& conn) -> void {
		OnConnection(conn);
		// 连接成功 计数器就-1
		if (conn->connected())	latch.countDown();
	});
	// 启动
	server_.start();
	latch.wait();	// 等待连接建立完成
}